//Bounseal
//# address-hook(0x08bade) end(0x08bade)
function void Penguin.Init()
{
	if customZoneSelect.useAlternates == 1 && customZoneSelect.alternateZoneSet == 0 && global.zone_act == 0x0500
	{
		Object.InitWithUpdateAddress(addressof(coldPeaksZone.updateBounseal))
		objA0.subtype2c = System.rand() % 8 == 0
	}
	else base.Penguin.Init()
}

//# address-hook(0x200410)
function void coldPeaksZone.updateBounseal()
{
	objA0.box_size.x = 0x40
	objA0.box_size.y = 0x40
	
	objA0.hitbox_extends.x = 12
	objA0.hitbox_extends.y = 12
	
	objA0.collision_attributes = (collision.size.24x24 | collision.flag.DESTRUCTIBLE)
	
	if objA0.countdown_value > 0
		objA0.countdown_value -= 1
	
	UpdateMovementStraightSimple()
	objA0.velocity.y += 0x40
	
	if objA0.velocity.x >= 0
	{
		D3 = 12
		fn00fac4()
	}
	else
	{
		D3 = -12
		fn00fe3c()
	}
	if (D1.s16 < 0)
	{
		if objA0.render_flags & render_flag.FLIP_X
		{
			objA0.render_flags &= ~render_flag.FLIP_X
			objA0.position.x.u16 -= 3
			objA0.countdown_value = 20
			objA0.velocity.x = -0x200
		}
		else
		{
			objA0.render_flags |= render_flag.FLIP_X
			objA0.position.x.u16 += 3
			objA0.countdown_value = 20
			objA0.velocity.x = 0x200
		}
	}
	
	CheckGroundCollision()
	if (D1.s16 <= 1)
	{
		if objA0.countdown_value == 0
		{
			objA0.velocity.x = (objA0.render_flags & render_flag.FLIP_X) ? 0x200 : -0x200 
			objA0.velocity.y = -0x600
			Audio.playAudio("coldpeakszone.bounseal.bounce")
			objA0.countdown_value = 10
		}
		else
		{
			objA0.velocity.y = 0
			objA0.velocity.x = 0
			CheckDistanceToPlayers()
			if D0 == 2
				objA0.render_flags |= render_flag.FLIP_X
			else objA0.render_flags &= ~render_flag.FLIP_X
		}
	}
	else
	{
		objA0.countdown_value = 10
	}
	
	D0 = u8[A0 + 0x29]
	if (D0.u8 == 0)
	{
		Enemy.DrawOrUnload()
		return
	}
	
	A1 = 0xffff0000 + u16[0x087910 + D0.u16 * 2]
	fn0857c2()
	if (_equal())
	{
		spawnChildObject(0x06b77c, 0x00, 0, 0)
		Object.TriggerUnloading()
	}
	else
	{
		DrawObject()
	}
}

//Blowler
//# address-hook(0x08be2e) end(0x08be2e)
function void StarPointer.Init()
{
	if customZoneSelect.useAlternates == 1 && customZoneSelect.alternateZoneSet == 0 && global.zone_act == 0x0500
	{
		Object.InitWithUpdateAddress(addressof(coldPeaksZone.updateBlowler))
	}
	else base.StarPointer.Init()
}

//# address-hook(0x200412)
function void coldPeaksZone.updateBlowler()
{
	objA0.box_size.x = 0x40
	objA0.box_size.y = 0x40
	
	objA0.hitbox_extends.x = 8
	objA0.hitbox_extends.y = 8
	
	objA0.collision_attributes = (collision.size.16x16 | collision.flag.DESTRUCTIBLE)
	objA0.sprite_priority = 0x200
	
	CheckDistanceToPlayers()
	if objA0.state == 0x00
	{
		if D0 == 2
			objA0.render_flags |= render_flag.FLIP_X
		else objA0.render_flags &= ~render_flag.FLIP_X
		
		UpdateMovementStraightSimple()
		if objA0.velocity.y < 0x100 && D1 == 2
			objA0.velocity.y += 0x40
		else if objA0.velocity.y > - 0x100 && D1 == 0
			objA0.velocity.y -= 0x40
		
		if objA0.velocity.x < -0x100
			objA0.velocity.x = -0x100
		else if objA0.velocity.x > 0x100
			objA0.velocity.x = 0x100
		
		objA0.velocity.x += (objA0.render_flags & render_flag.FLIP_X) ? 0x40 : -0x40
	}
	
	if (D2.u16 < 0x60 && D3.u16 < 0x20 && objA0.state == 0) || objA0.state == 1
		objA0.value32 += 1
	
	if objA0.value32 > 1 && objA0.value32 < 180
	{
		objA0.state = 0x01
	}
	else
	{
		objA0.value3e = 0
		objA0.state = 0x00
	}
	
	if objA0.value32 > 360	
		objA0.value32 = 0
	
	if objA0.state == 1
	{
		playSoundRepeatedly(0xda)
		if global.framecounter % 24 == 0
			coldPeaksZone.spawnBlowlerWind(objA0.render_flags & render_flag.FLIP_X)
		if D2.u16 < 0x80 && D3.u16 < 0x20 && !(u8[A1 + 0x20] == char.state.KNUX_FLYCLIMB && s16[A1 + 0x18] == 0)
		{
			s16 pushSpeed = 0x30 / Math.roundToInt(float(D3.u16) / 10.5f)
			if (objA0.render_flags & render_flag.FLIP_X)
			{
				if D0 == 2
				{
					if s16[A1 + 0x18] < 0
						s16[A1 + 0x18] = 0
					else s16[A1 + 0x18] += pushSpeed
					
					if s16[A1 + 0x1c] < 0
						s16[A1 + 0x1c] = 0
					else s16[A1 + 0x1c] += pushSpeed
				}
			}
			else
			{
				if D0 == 0
				{
					if s16[A1 + 0x18] > 0
						s16[A1 + 0x18] = 0
					else s16[A1 + 0x18] -= pushSpeed
					
					if s16[A1 + 0x1c] > 0
						s16[A1 + 0x1c] = 0
					else s16[A1 + 0x1c] -= pushSpeed
				}
			}
		}
	}
	
	D0 = u8[A0 + 0x29]
	if (D0.u8 == 0)
	{
		Enemy.DrawOrUnload()
		return
	}
	
	A1 = 0xffff0000 + u16[0x087910 + D0.u16 * 2]
	fn0857c2()
	if (_equal())
	{
		spawnChildObject(0x06b77c, 0x00, 0, 0)
		Object.TriggerUnloading()
	}
	else
	{
		DrawObject()
	}
}
function void coldPeaksZone.spawnBlowlerWind(bool flip)
{
	if (allocDynamicObjectStd())
	{
		objA1.position.x.u16 = objA0.position.x.u16
		objA1.position.y.u16 = objA0.position.y.u16 - 8 + global.framecounter % 16
		objA1.update_address = addressof(coldPeaksZone.updateBlowlerWind)
		objA1.render_flags = (render_flag.WORLD | render_flag.VISIBLE)
		if flip
			objA1.render_flags |= render_flag.FLIP_X
		objA1.value32 = 100
	}
}

//# address-hook(0x200416)
function void coldPeaksZone.updateBlowlerWind()
{
	DrawObject()
	
	UpdateMovementStraightSimple()
	
	if (objA0.render_flags & render_flag.FLIP_X)
		objA0.velocity.x += 0x60
	else objA0.velocity.x -= 0x60
	
	if objA0.value32 > 0
		objA0.value32 -= 1

	if abs(objA0.velocity.x) > 0xe00
		UnloadObject()
	if !(objA0.render_flags & render_flag.VISIBLE)
		UnloadObject()
}

function bool Standalone.onWriteToSpriteTable(s16 px, s16 py, u16 renderQueue)
{
	if objA0.update_address == 0x200410
	{
		string key
		if objA0.countdown_value == 10
			key = stringformat("coldPeaksZone.bounseal%s_0x0%d", objA0.subtype2c ? "_glasses" : "", 2 + (global.framecounter / 10) % 2)
		else key = stringformat("coldPeaksZone.bounseal%s_0x0%d", objA0.subtype2c ? "_glasses" : "", (global.framecounter / 10) % 2)
		Renderer.drawCustomSprite(key, px, py, 0x10, (objA0.render_flags & render_flag.FLIP_X), renderQueue)
	}
	if objA0.update_address == 0x200412
	{
		string key
		if objA0.state == 0x01 && (global.framecounter / 4) % 2 == 0
			Renderer.drawCustomSprite("coldPeaksZone.blowler_0x02", px, py, 0x10, (objA0.render_flags & render_flag.FLIP_X) | 0x40, renderQueue)
		key = stringformat("coldPeaksZone.blowler_0x0%d", (global.framecounter / 10) % 2)
		Renderer.drawCustomSprite(key, px, py, 0x10, (objA0.render_flags & render_flag.FLIP_X) | 0x40, renderQueue)
		if global.framecounter % 2 == 0
			Renderer.drawCustomSprite("coldPeaksZone.blowler_0x03", px, py, 0x10, (objA0.render_flags & render_flag.FLIP_X) | 0x40, renderQueue)
	}
	if objA0.update_address == 0x200416
	{
		SpriteHandle wind = Renderer.addSpriteHandle("coldPeaksZone.blowler_0x04", px, py, renderQueue)
		wind.setFlags(0x40)
		wind.setBlendMode(3)
		wind.setPaletteOffset(0x10)
	}
	return base.Standalone.onWriteToSpriteTable(px, py, renderQueue)
}
